function InversePairs(data)
{
    // write code here
    // 定义这个归并排序的函数,输入的参数是左右边界
    function mergeSort(L,R){ //输入的参数是左边界和有边界 左右两边都是闭区间
      // 递归的出口是 
      if(L >= R) { // 如果左边界大于等于有边界了 那么就是最多只剩下一个元素了 那么现在这时的逆序对的个数是0
        return 0
      }
      // 否则的话是计算中间的数值
      var mid = L + Math.floor((R - L) / 2)
      // 先让逆序对的个数等于 将这个数组左右两边对半分的逆序对之和
      var cnt = mergeSort(L,mid) + mergeSort(mid+1,R)
      // 然后再让他加上这两个相邻子数组之间的逆序对的个数 是在等会将这两个子数组排序过程中统计出来的
      // 左右两个子数组已经是有序的了 我们需要的是合并这两个子数组
      // 我们用i,j 分别指向左边子数组和右边子数组的其实位置
      var i = L
      var j = mid + 1
      // 用pos指向的是将要把这个数合并到这个辅助数组当中的位置
      var pos = L  // 就是这个的左边界
      while(i <= mid && j <= R){ // 循环的条件是i和j都不超过有边界
        // 如果说是左边的子数组当中的数字小于等于右边的子数组当中的数字
        if(data[i] <= data[j]){
          // 我们就将左边的数字加入到临时数组中
          temp[pos] = data[i]
          // 同时将i+1
          i++
        }else{ // 否则的话说明右边的子数组当中的数 是比左边的子数组当中的数小的 那么我们将右边的数字放入到辅助数组当中
          temp[pos] = data[j] // 将这个数字放入到pos的位置上          
          j++
          cnt += (mid - i + 1) // 后面的数字就是逆序对的个数 将其加到逆序对个数中
        }
        // 将数字放入到临时数组之后呢就让pos加1
        pos++ // 让pos向后移动一位
      }
      // 最后可能某一个数组当中的数字已经全部放入辅助数组当中
      // 那么我们需要将剩余数组当中所有元素直接加入到数组当中
      // 由于我们不知道是哪个合并完了 所有我们可以将两个都写出来
      for(let k = i ; k < mid+1 ;k++){
        temp[pos] = data[k]
        pos++
      }
      for(let k = j ; k < R+1 ; k++){
        temp[pos] = data[k]
        pos++
      } // 将两个子数组合并成了一个有序的数组 
      // 需要将排序的结果拷贝到原来的数组当中
      data.splice(L,R-L+1,...temp.slice(L,R+1)) // 将temp解构 然后替换l_r+1位置的元素 第一个参数删除的位置 第二个参数 删除几个 第三参数插入的元素
      return cnt // 并且返回我们的逆序对的个数
    }
    var n = data.length // 获取给定数组的长度 记为n
    // 初始化一个大小为n的辅助数组
    var temp = new Array(n)
    return mergeSort(0,n-1)%1000000007 // 返回的答案就是调用归并排序 排序的内容就是从0到n-1的闭区间
}
module.exports = {
    InversePairs : InversePairs
};